<template>
  <div class="datetime-converter">
    <div class="datetime-converter-container">
      <div class="converter-header">
        <h1>日期时间转换器</h1>
        <p class="subtitle">将日期和时间转换为各种不同的格式</p>
      </div>
      <!-- 输入区域 -->
      <div class="input-section">
        <div class="input-group">
          <a-input v-model:value="inputTime" placeholder="请输入要转换的日期..." @change="handleInputChange" @input="handleInput" @keydown.stop allowClear />
          <a-select v-model:value="selectedFormat" style="width: 120px">
            <a-select-option value="auto">时间戳</a-select-option>
            <a-select-option value="date">日期格式</a-select-option>
          </a-select>
        </div>
      </div>

      <!-- 转换结果展示区域 -->
      <div class="result-section">
        <div class="result-grid">
          <div v-for="(value, key) in timeFormats" :key="key" class="result-item">
            <div class="format-label">{{ value.label }}</div>
            <div class="format-value">
              {{ convertedTime[key] || '-' }}
              <a-button type="link" class="copy-btn" @click="copyToClipboard(convertedTime[key])">
                <template #icon><CopyOutlined /></template>
              </a-button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import utc from 'dayjs/plugin/utc'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import 'dayjs/locale/zh-cn'
import { CopyOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'

// 配置 dayjs
dayjs.extend(relativeTime)
dayjs.extend(utc)
dayjs.extend(customParseFormat)
dayjs.locale('zh-cn')

const inputTime = ref('')
const selectedFormat = ref('auto')
let timer = null // 用于存储定时器
let isRealTime = ref(true) // 控制是否显示实时时间

// 初始化时获取当前时间
const initCurrentTime = () => {
  const now = dayjs()
  if (isRealTime.value && !inputTime.value) {
    handleInputChange(now.format('YYYY-MM-DD HH:mm:ss'))
  }
}

// 开始实时更新时间
const startRealTimeUpdate = () => {
  timer = setInterval(() => {
    initCurrentTime()
  }, 1000)
}

// 停止实时更新
const stopRealTimeUpdate = () => {
  if (timer) {
    clearInterval(timer)
    timer = null
  }
}

// 处理输入框输入事件
const handleInput = (e) => {
  const value = e.target.value
  if (!value) {
    isRealTime.value = true
    startRealTimeUpdate()
    initCurrentTime() // 立即更新一次当前时间
  } else {
    isRealTime.value = false
    stopRealTimeUpdate()
    handleInputChange(value) // 立即处理输入的值
  }
}

// 处理输入变化
const handleInputChange = (value) => {
  let inputValue = value || inputTime.value
  if (!inputValue) {
    resetConvertedTime()
    return
  }

  let date
  inputValue = String(inputValue).trim()

  // 尝试解析输入
  if (/^\d{10}$/.test(inputValue)) {
    // 10位时间戳（秒）
    date = dayjs.unix(parseInt(inputValue))
  } else if (/^\d{13}$/.test(inputValue)) {
    // 13位时间戳（毫秒）
    date = dayjs(parseInt(inputValue))
  } else {
    // 尝试作为普通日期字符串解析
    date = dayjs(inputValue)
  }

  if (date.isValid()) {
    updateConvertedTime(date)
  } else {
    resetConvertedTime()
  }
}

// 更新转换结果
const updateConvertedTime = (date) => {
  Object.keys(timeFormats).forEach((key) => {
    try {
      convertedTime[key] = timeFormats[key].format(date)
    } catch (error) {
      convertedTime[key] = '-'
    }
  })
}

// 重置转换结果
const resetConvertedTime = () => {
  Object.keys(convertedTime).forEach((key) => {
    convertedTime[key] = ''
  })
}

// 复制到剪贴板
const copyToClipboard = async (text) => {
  try {
    await navigator.clipboard.writeText(text)
    message.success('已复制到剪贴板')
  } catch (err) {
    message.error('复制失败')
  }
}

// 生成 Mongo ObjectID
const generateMongoObjectId = (date) => {
  const timestamp = Math.floor(date.valueOf() / 1000).toString(16)
  const randomPart = Math.random().toString(16).substring(2, 14)
  return timestamp.padStart(8, '0') + randomPart
}

// 获取 Excel 序列号
const getExcelSerial = (date) => {
  const epoch = dayjs('1900-01-01')
  const days = date.diff(epoch, 'day')
  const fraction = (date.hour() * 3600 + date.minute() * 60 + date.second()) / 86400
  return (days + 2 + fraction).toString()
}

// 定义时间格式配置
const timeFormats = {
  jsDate: { label: 'js设置日期字符串', format: (date) => date.format('ddd MMM DD YYYY HH:mm:ss [GMT]Z [(中国标准时间)]') },
  iso8601: { label: 'ISO 8601', format: (date) => date.format('YYYY-MM-DDTHH:mm:ssZ') },
  iso9075: { label: 'ISO 9075', format: (date) => date.format('YYYY-MM-DD HH:mm:ss') },
  rfc3339: { label: 'RFC 3339', format: (date) => date.format('YYYY-MM-DDTHH:mm:ssZ') },
  rfc7231: { label: 'RFC 7231', format: (date) => date.toDate().toUTCString() },
  unixTimestamp: { label: 'Unix 时间戳', format: (date) => date.unix() },
  timestamp: { label: '时间戳', format: (date) => date.valueOf() },
  utcFormat: { label: 'UTC 格式', format: (date) => date.utc().format('ddd, DD MMM YYYY HH:mm:ss [GMT]') },
  mongoObjectId: { label: 'Mongo ObjectID', format: (date) => generateMongoObjectId(date) },
  excelSerial: { label: 'Excel 日期/时间', format: (date) => getExcelSerial(date) }
}

const convertedTime = reactive({
  jsDate: '',
  iso8601: '',
  iso9075: '',
  rfc3339: '',
  rfc7231: '',
  unixTimestamp: '',
  timestamp: '',
  utcFormat: '',
  mongoObjectId: '',
  excelSerial: ''
})

// 组件挂载时启动实时更新
onMounted(() => {
  isRealTime.value = true
  startRealTimeUpdate()
  initCurrentTime()
})

// 组件卸载时清理
onUnmounted(() => {
  stopRealTimeUpdate()
})
</script>

<style scoped>
.datetime-converter-container {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  background: #ffffff;
  color: #333;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  padding: 30px;
}
.datetime-converter {
  padding: 20px;
  width: 100%;
  margin: 0 auto;
  color: #333;
  min-height: 100vh;
}

.converter-header {
  text-align: center;
  margin-bottom: 30px;
}

.converter-header h1 {
  color: #333;
  margin-bottom: 10px;
}

.subtitle {
  color: #666;
  margin-bottom: 20px;
}

.input-section {
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
}

.input-group {
  display: flex;
  gap: 10px;
  width: 100%;
  max-width: 600px;
}

.result-section {
  margin-top: 20px;
}

.result-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
  gap: 15px;
}

.result-item {
  background: #f5f5f5;
  padding: 15px;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
}

.format-label {
  color: #666;
  font-size: 14px;
  margin-bottom: 8px;
}

.format-value {
  color: #333;
  font-family: monospace;
  display: flex;
  justify-content: space-between;
  align-items: center;
  word-break: break-all;
}

.copy-btn {
  color: #666;
  padding: 4px;
  &:hover {
    color: #1890ff;
  }
}
</style>
